package edu.thu.studio.ormdesigner.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import com.thoughtworks.xstream.annotations.XStreamImplicit;

public abstract class ObjectSet<T extends AbstractModel> extends AbstractModel implements Iterable<T> {
    
    private static final long serialVersionUID = 1L;
    
    @XStreamImplicit()
    protected List<T> objectList = new ArrayList<T>();
    
    public ObjectSet() {
    }
    
    public void clear() {
        this.objectList.clear();
    }
    
    @SuppressWarnings("unchecked")
    public void addObject(Object object) {
        this.objectList.add((T) object);
    }
    
    public int remove(Object object) {
        int index = this.objectList.indexOf(object);
        if(index>-1){
            this.objectList.remove(index);
        }
        return index;
    }
    
    public boolean contains(String id) {
        for (T object : objectList) {
            if (id.equalsIgnoreCase(object.getId())) {
                return true;
            }
        }
        
        return false;
    }
    
    public int indexOf(Object object) {
        return objectList.indexOf(object);
    }
    
    @SuppressWarnings("unchecked")
    public void addObject(int index, Object object) {
        objectList.add(index, (T) object);
    }
    
    public boolean contains(AbstractModel model) {
        if (null != model && null != model.getId()) {
            for (T object : objectList) {
                if (model.getId().equalsIgnoreCase(object.getId())) {
                    return true;
                }
            }
        }
        return false;
    }
    
    public T get(String id) {
        for (T object : objectList) {
            if (id.equalsIgnoreCase(object.getId())) {
                return object;
            }
        }
        
        return null;
    }
    
    public List<T> getObjectList() {
        return this.objectList;
    }
    
    public Iterator<T> iterator() {
        return this.objectList.iterator();
    }
    
    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Override
    public ObjectSet<T> clone() {
        ObjectSet<T> objectSet = (ObjectSet<T>) super.clone();
        List<T> newObjectList = new ArrayList<T>();
        
        for (T object : this.objectList) {
            T newObject = (T) object.clone();
            newObjectList.add(newObject);
        }
        
        objectSet.objectList = newObjectList;
        
        return objectSet;
    }
    
    @SuppressWarnings("unchecked")
    public AbstractModel cloneAsNew() {
        ObjectSet<T> objectSet = (ObjectSet<T>) super.cloneAsNew();
        List<T> newObjectList = new ArrayList<T>();
        
        for (T object : this.objectList) {
            T newObject = (T) object.cloneAsNew();
            newObjectList.add(newObject);
        }
        
        objectSet.objectList = newObjectList;
        
        return objectSet;
    }
    
    public String getObjectType() {
        return "list";
    }
    
    public String getDescription() {
        return "";
    }
    
}
